#ifndef _TOKEN_INCLUDED_
#define _TOKEN_INCLUDED_

#include "TokenTyp.h"
#include <iostream>

/**
* Base class of all tokens. Signs like +, -, *, / and so on will only need this base class. They can be
* identified by tokenTyp.
*
* Beneath you can see the derived classes which will inherited from Token.
* So tokens like DOUBLE, INTEGER, IDENTIFIER and so on will have a own class.
*
* \author Andy Albert Fuchs
*/
class Token {
	/// Possibility to name the token. The name will appear if the token will be printed out on ostream.
	char*	name;
	/// Typ of token (Can be chosen by taking enumeration <code>TokenTyp</code>)
	int		tokenTyp;
	/// Line and Column of the token
	int		line, column;

public:

	/**
	* Constructor. Initialize token.
	*
	* \param line		Line of token
	* \param column		Column of token
	* \param name		Name of Tokens
	* \param tokenTyp	Typ of token
	*/
	Token(int line, int column, char* name, int tokenTyp) {
		this->line = line;
		this->column = column;
		this->name = name;
		this->tokenTyp = tokenTyp;
	}

	int getTokenTyp() const {
		return this->tokenTyp;
	}

	int getLine() const {
		return this->line;
	}

	int getColumn() const {
		return this->column;
	}

	char* getName() {
		return this->name;
	}
};

/**
* Token Identifier. Saves the lexem pointer and the length. Inherites from Token.
*/
class TokenIdent : public Token {
	/// Pointer of lexem
	char* lexem;
	/// Length of the lexem
	int length;

public:

	/**
	* Initializes the token.
	* 
	* \param line	Line of token
	* \param column	Column of token
	* \param lexem	Pointer of the lexem
	* \param length	Length of the lexem
	*/
	TokenIdent(int line, int column, char* lexem, int length) : Token(line, column, (char*) "Identifier", TokenTyp::TOKEN_IDENT) {
		this->lexem = lexem;
		this->length = length;
	}

	char* getLexem() const {
		return this->lexem;
	}

	int getLength() const {
		return this->length;
	}
};

/**
* Token Integer. Saves the value of a long figure. Inherites from Token.
*/
class TokenInteger : public Token {
	/// Long value of the integer value
	long value;

public:

	/**
	* Initializes the token
	* 
	* \param line	Line of the token
	* \param column	Column of the token
	* \param value	Long Value of the token
	*/
	TokenInteger(int line, int column, long value) : Token(line, column, (char*) "Integer", TokenTyp::TOKEN_INTEGER) {
		this->value = value;
	}

	long getValue() const {
		return this->value;
	}

};

/**
* Token Real. Saves the value of a double figure. Inherites from Token.
*/
class TokenReal : public Token {
	/// Double value of the Token Real
	double value;

public:
	/**
	* Initializes the token
	* 
	* \param line	Line of the token
	* \param column	Column of the token
	* \param value	Double value of the token
	*/
	TokenReal(int line, int column, double value) : Token(line, column, (char*) "Real", TokenTyp::TOKEN_REAL) {
		this->value = value;
	}

	double getValue() const {
		return this->value;
	}
};

/**
* Token Product. Saves name for output and token typ.
*/
class TokenProduct : public Token {

public:
	/**
	* Initializes the token
	* 
	* \param line	Line of the token
	* \param column	Column of the token
	*/
	TokenProduct(int line, int column) :  Token(line, column, (char*) "Product", TokenTyp::TOKEN_PROD) {
	}
};

/**
* Token Sum. Saves name for output and token typ.
*/
class TokenSum : public Token {

public:
	/**
	* Initializes the token
	* 
	* \param line	Line of the token
	* \param column	Column of the token
	*/
	TokenSum(int line, int column) :  Token(line, column, (char*) "Sum", TokenTyp::TOKEN_SUM) {
	}
};

/**
 *	Token Print. Saves name for output and token typ.
 */

class TokenPrint : public Token {
	public:

	/**
	* Initializes the token
	* 
	* \param line	Line of the token
	* \param column	Column of the token
	*/
	TokenPrint(int line, int column) :  Token(line, column, (char*) "Print", TokenTyp::TOKEN_PRINT) {
	}
};

/**
 *	Token Durch. Saves name for output and token typ.
 */

class TokenDurch : public Token {
	public:

	/**
	* Initializes the token
	* 
	* \param line	Line of the token
	* \param column	Column of the token
	*/
	TokenDurch(int line, int column) :  Token(line, column, (char*) "Durch", TokenTyp::TOKEN_DURCH) {
	}
};

/**
 *	Token Print. Saves name for output and token typ.
 */
class TokenModulo : public Token {
	public:

	/**
	* Initializes the token
	* 
	* \param line	Line of the token
	* \param column	Column of the token
	*/
	TokenModulo(int line, int column) :  Token(line, column, (char*) "Modulo", TokenTyp::TOKEN_MODULO) {
	}
};

/**
*	"<<"-Operator overloaded. So all classes which are derived from Token and of course itself 
*	can be printed here
*/
std::ostream& operator<<(std::ostream& cout, Token& token);
#endif // _TOKEN_INCLUDED_
